Scrapy框架之Scrapy-Splash的使用

Scrapy-Splash插件的介绍与安装, 最后通过一个实际的例子介绍Scrapy-Splash的使用

前提

熟练使用Scrapy框架做基本的爬虫开发

Scrapy-Splash?

splash是一个JavaScript渲染服务。它是一个实现了HTTP API的轻量级浏览器,splash使用python实现的,同时使用Twisted和QT.

scrapy-splash 是为了方便scrapy框架使用splash而进行的封装。它能与scrapy框架更好的结合,相比较于在python中 使用requests库或者使用scrapy 的Request对象来说,更为方便,而且能更好的支持异步。

Why Scrapy-Splash?

随着越来越多的网站开始用JS在客户端浏览器动态渲染网站,导致很多我们需要的数据并不能由原始的html中获取,再加上Scrapy本身并不提供JS渲染解析的功能,这时候Scrapy-Splash就有了用武之地.

Scrapy-Splash Install

因为Scrapy-Splash必须在docker中使用, 所以首先得安装docker, 安装docker的方式这里不做介绍了. 我这里使用的机器是Ubuntu18.04, 在Ubuntu18.04上安装docker参考文章: 在Ubuntu18.04上安装docker

安装完docker之后, 通过sudo docker run -p 8050:8050 scrapinghub/splash启动Scrapy-Splash, 在浏览器中输入: http://localhost:8050/, 如果显示的是以下界面这一切操作成功:

scrapy-splash界面.png
Scrapy-Splash Usage

这里以抓取某篇具体小说为例: 小说地址为 http://www.biqugedu.com/0_25/, 这里我们要抓取它的封面图.

xpath路经.png

通过在浏览器中分析, 封面图的xpath路经为: //div[@id='fmimg']/img/@src, 然后我们编写一个parse解析方式, 打印出抓取到的封面图地址:

    def parse(self, response):
        print(response.xpath("//div[@id='fmimg']/img/@src").extract_first())

往Redis中推送任务后运行爬虫, 发现输出为:

2019-02-27 10:07:21 [scrapy.core.engine] INFO: Spider opened
2019-02-27 10:07:23 [dmoz] DEBUG: Resuming crawl (1 requests scheduled)
2019-02-27 10:07:23 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-02-27 10:07:23 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-02-27 10:07:27 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.biqugedu.com/0_25/> (referer: None)
None
2019-02-27 10:07:28 [dmoz] INFO: no task sleep 30s
2019-02-27 10:07:32 [scrapy.crawler] INFO: Received SIGINT, shutting down gracefully. Send again to force 
2019-02-27 10:07:32 [scrapy.core.engine] INFO: Closing spider (shutdown)

很显然没有抽取到我们期望的内容, 然后回过头来发现, 原页面中封面地址实际上是通过一个js脚本加载的, 而在浏览器中能够看到xpath是因为浏览器已经帮我们把这个js加载好了, 但是Scrapy框架则只会请求这个小说的文件, 不会加载其中的js, 如果想要加载js, 这个时候就需要Scrapy-Splash就登场了.

在开始使用Scrapy-Splash之前, 先把这个小说地址添加到Splash中Render一下(上边提到的启动Splash服务后在浏览器中输入http://localhost:8050), 然后可以看到正常获取到了图片地址

Splash Render后的结果

接下来, pip install scrapy_splash安装scrapy_splash, 然后编写一个start_requests方法:

def start_requests(self):
    splah_args = {
        "lua_source": """
        function main(splash, args)
          assert(splash:go(args.url))
          assert(splash:wait(0.5))
          return {
            html = splash:html(),
            png = splash:png(),
            har = splash:har(),
          }
        end
        """
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/72.0.3626.109 Safari/537.36',
    }
    yield SplashRequest(url="http://www.biqugedu.com/0_25/", callback=self.parse, args=splah_args, 
 headers=headers)

然后在settings文件中进行如下配置:

# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
SPIDER_MIDDLEWARES = {
   'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}

# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,  # 不配置查不到信息
}

HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'

SPLASH_URL = "http://localhost:8050/"  # 自己安装的docker里的splash位置
# DUPEFILTER_CLASS = "scrapy_splash.SplashAwareDupeFilter"
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

这时再启动爬虫程序, 结果如下:

2019-02-27 10:45:17 [scrapy.extensions.httpcache] DEBUG: Using filesystem cache storage in /home/tiger/PycharmProjects/tutorial/.scrapy/httpcache
2019-02-27 10:45:17 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-02-27 10:45:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.biqugedu.com/0_25/ via http://localhost:8050/render.html> (referer: None)
http://www.biqugedu.com/files/article/image/0/25/25s.jpg
2019-02-27 10:45:25 [dmoz] INFO: no task sleep 30s

正常输出了封面图的地址.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容